﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Text;
using VPLink2014.Data;
using VPLink2014.Data.MesApplis;

namespace VPLink2013.Batch
{
    public class Program
    {
        private static StringBuilder sbTrace;

        #region Helper
        private static void SaveTrace(string fileName)
        {
            try
            {
                string strPath = System.Environment.CurrentDirectory + @"\" + fileName;
                System.IO.File.WriteAllText(strPath, sbTrace.ToString(), Encoding.UTF8);
                sbTrace = new StringBuilder();
            }
            catch (System.Exception exc)
            {
                Console.WriteLine(exc.Message);
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", exc.Message, exc.StackTrace));
            }
        }


        private static int getAppliIdByName(string applicationTitle)
        {
            int appId = -1;
            try
            {
                using (VPLinkLogConnection db = new VPLinkLogConnection())
                {
                    Application appDb = (from u in db.VplinkEntities.Applications
                                          where u.titre == applicationTitle
                                          select u).FirstOrDefault();
                    if (appDb != null)
                    {
                        appId = appDb.id;
                    }
                    else
                    {
                        Console.WriteLine("L'application {0} n'a pas été trouvé", applicationTitle);
                        sbTrace.AppendLine(string.Format("l'application {0} n' pas a été trouvé", applicationTitle));
                    }
                }
            }
            catch (Exception ex)
            {
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", ex.Message, ex.StackTrace));
            }
            return appId;
        }
        #endregion

        static void Main(string[] args)
        {
            sbTrace = new StringBuilder();
            string allDistribListName = ConfigurationSettings.AppSettings["distribGroupNames"];
            string applicationsSettings = ConfigurationSettings.AppSettings["applicationsTitle"];
            string[] applicationsTitle = applicationsSettings.Split(';');
            string[] distribListTab = allDistribListName.Split(';');
            foreach (string applicationTitle in applicationsTitle)
            {
                int appliId = -1;
                appliId = getAppliIdByName(applicationTitle);
                Console.WriteLine("Treatement de l'application {0}", applicationTitle);
                foreach (string distribListName in distribListTab)
                {
                    AttachListToApplication(distribListName, appliId);
                    SaveTrace(string.Format("trace_{0}_{1}.txt", distribListName, applicationTitle));
                }
            }
        }

        private static void AddApplicationToUser(int applicationID, VPLinkLogConnection db, string userLogin)
        {
            VOUserMapper user = new VOUserMapper(userLogin);
            if (user.user != null)
            {
                sbTrace.AppendLine(string.Format("Traitement de : {0}", userLogin));
                List<VOApplication> applications = new List<VOApplication>();
                foreach (var app in db.VplinkEntities.GetSelectedApplicationsForUser(userLogin))
                {
                    applications.Add(new VOApplication()
                    {
                        Id = app.id
                    });
                }
                if (!applications.Any(x => x.Id == applicationID))
                {
                    applications.Add(new VOApplication()
                    {
                        Id = applicationID
                    });
                    user.SetApplications(applications);
                    sbTrace.AppendLine(string.Format("ajout application {0} réussi", applicationID));
                }
                else
                {
                    Console.WriteLine(string.Format("L'utilisateur {0} a déja lapplication {1}", userLogin, applicationID));
                    sbTrace.AppendLine(string.Format("L'utilisateur {0} a déja lapplication {1}", userLogin, applicationID));
                }
            }
            else
            {
                Console.WriteLine(string.Format("L'utilisateur {0} n'a pas été trouvé dans la base", userLogin));
                sbTrace.AppendLine(string.Format("L'utilisateur {0} n'a pas été trouvé dans la base", userLogin));
            }
        }

        private static void treatPrincipal(int applicationID, VPLinkLogConnection db, Principal p)
        {
            UserPrincipal user = p as UserPrincipal;
            if (user != null)
            {
                string userLogin = string.Format("oredis-vp\\{0}", user.SamAccountName);
                AddApplicationToUser(applicationID, db, userLogin);
            }
            else
            {
                GroupPrincipal group = p as GroupPrincipal;
                if (group != null)
                {
                    sbTrace.AppendLine(string.Format("Traitement du sous groupre {0}", group.Name));
                    PrincipalSearchResult<Principal> members = group.GetMembers();
                    foreach (Principal member in members)
                    {
                        treatPrincipal(applicationID, db, member);
                    }
                }
            }
        }

        public static void AttachListToApplication(string distributionGroup, int applicationID)
        {
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
            GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, distributionGroup);
            if (group != null)
            {
                PrincipalSearchResult<Principal> members = group.GetMembers();
                sbTrace.AppendLine(string.Format("il y a {0} membres dans la liste de distribution {1}", members.Count(), distributionGroup));
                Console.WriteLine(string.Format("il y a {0} membres dans la liste de distribution {1}", members.Count(), distributionGroup));
                try
                {
                    using (VPLinkLogConnection db = new VPLinkLogConnection())
                    {
                        foreach (Principal member in members)
                        {
                            treatPrincipal(applicationID, db, member);
                        }
                    }
                }
                catch (Exception e)
                {
                    sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", e.Message, e.StackTrace));
                }
            }
            else
            {
                Console.WriteLine("La liste de distribution n'existe pas");
                sbTrace.AppendLine(string.Format("La liste de distribution {0} n'existe pas", distributionGroup));
            }
        }
    }
}
